home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Amster - File sharing
- ** by Jacob Laursen <laursen@myself.com>
- */
-
- #include "include/config.h"
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "include/mui.h"
- #include <MUI/NListview_mcc.h>
-
- #include <proto/asl.h>
- #include <proto/dos.h>
-
- #include <libraries/asl.h>
- #include <libraries/dos.h>
-
- #include <exec/memory.h>
- #include <dos/exall.h>
- #include <utility/tagitem.h>
- #include <workbench/workbench.h>
-
- #include "md5.h"
- #include "include/protos.h"
- #include "include/gui.h"
- #include "include/info.h"
- #include "include/share.h"
- #include "include/prefs.h"
- #include "include/panel.h"
- #include "include/napster.h"
- #include "include/upload.h"
- #include "include/rexx.h"
- #include "amster_Cat.h"
-
-
- unsigned int numsongs=0, numbytes=0;
- BOOL sharechanged=FALSE, sharefailed=FALSE;
-
- struct FileRequester *FReqAddFiles;
- struct FileRequester *FReqAddDir;
- struct FileRequester *FReqLibrary;
-
-
- MUIF share_dispatch(REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg)
- {
- struct shdata *data;
-
- switch(msg->MethodID) {
- case OM_NEW:
- return(share_new(cl, obj, (APTR)msg));
- case OM_DISPOSE:
- if (FReqAddFiles) FreeAslRequest(FReqAddFiles);
- if (FReqAddDir) FreeAslRequest(FReqAddDir);
- if (FReqLibrary) FreeAslRequest(FReqLibrary);
- break;
- case SHARE_OPEN:
- data = INST_DATA(cl, obj);
- update_stat(data);
- set(obj, MUIA_Window_Open, TRUE);
- return NULL;
- case SHARE_CLOSE:
- set(obj, MUIA_Window_Open, FALSE);
- return NULL;
- case SHARE_ADD:
- data = INST_DATA(cl, obj);
- add_shares(data);
- return NULL;
- case SHARE_ADDDIR:
- data = INST_DATA(cl, obj);
- add_directory(data);
- return NULL;
- case SHARE_REMOVE:
- data = INST_DATA(cl, obj);
- remove_shares(data, (long)(((muimsg)msg)->arg1));
- return NULL;
- case SHARE_SAVE:
- data = INST_DATA(cl, obj);
- save_shares(data);
- return NULL;
- case SHARE_SAVEAS:
- data = INST_DATA(cl, obj);
- save_shares_as(data);
- return NULL;
- case SHARE_LOAD:
- data = INST_DATA(cl, obj);
- load_shares(data);
- return NULL;
- case SHARE_LOADAS:
- data = INST_DATA(cl, obj);
- load_shares_as(data);
- return NULL;
- case SHARE_UPLOAD:
- data = INST_DATA(cl, obj);
- upload_file_confirm(data, (char *)(((muimsg)msg)->arg1), (char *)(((muimsg)msg)->arg2));
- return NULL;
- case SHARE_NOTIFYALL:
- data = INST_DATA(cl, obj);
- notify_shares(data);
- return NULL;
- case SHARE_PLAY:
- data = INST_DATA(cl, obj);
- play_share(data);
- return NULL;
- case SHARE_ADDFILE:
- data = INST_DATA(cl, obj);
- add_file(data, (song)(((muimsg)msg)->arg1), (char *)(((muimsg)msg)->arg2));
- return NULL;
- case SHARE_ADDFILEN:
- data = INST_DATA(cl, obj);
- add_filename(data, (char *)(((muimsg)msg)->arg1));
- return NULL;
- case SHARE_SETDIR:
- strcpy(FReqAddFiles->fr_Drawer, (char *)(((muimsg)msg)->arg1));
- strcpy(FReqAddDir->fr_Drawer, (char *)(((muimsg)msg)->arg1));
- return NULL;
- case SHARE_UPDCOUNT:
- data = INST_DATA(cl, obj);
- update_count(data, (char *)(((muimsg)msg)->arg1));
- return NULL;
- }
- return(DoSuperMethodA(cl, obj, msg));
- }
-
-
- MUIF sharelistdest(REG(a2) APTR pool, REG(a1) sharedata sd)
- {
- char *path;
-
- numsongs--;
- numbytes -= sd->size;
- if (gui_napon) {
- path = MakeWinPath(sd->title);
- nap_sendbuf(NAPC_REMOVESHARE, path);
- free(path);
- }
- free(sd);
-
- return(0);
- }
-
-
- MUIF sharelistdisp(REG(a2) char **array, REG(a1) sharedata sd)
- {
- static char size[16], md5[33], time[20], bitrate[16], freq[16], count[16];
-
- if (sd) {
- *array++ = sd->title;
- sprintf(size, "\33r%ld", sd->size);
- *array++ = size;
- sprintf(time, "\33r%ld:%02ld", sd->time/60, sd->time%60);
- *array++ = time;
- sprintf(bitrate, "\33r%ld", sd->bitrate);
- *array++ = bitrate;
- sprintf(freq, "\33l%ld", sd->freq);
- *array++ = freq;
- sprintf(count, "\33r%ld", sd->reqcount);
- *array++ = count;
- strcpy(md5, sd->md5);
- *array = md5;
- } else {
- *array++ = (char *)MSG_LH_FILE;
- *array++ = (char *)MSG_LH_SIZE;
- *array++ = (char *)MSG_LH_TIME;
- *array++ = (char *)MSG_LH_BITRATE;
- *array++ = (char *)MSG_LH_FREQ;
- *array++ = (char *)MSG_LH_COUNT;
- *array = (char *)MSG_LH_CHECKSUM;
- }
- return(0);
- }
-
-
- MUIF sharelistcomp(REG(a0) struct Hook *hook, REG(a2) Object *obj, REG(a1) struct NList_CompareMessage *ncm)
- {
- sharedata entry1 = ncm->entry1;
- sharedata entry2 = ncm->entry2;
- LONG col1 = ncm->sort_type & MUIV_NList_TitleMark_ColMask;
- LONG col2 = ncm->sort_type2 & MUIV_NList_TitleMark2_ColMask;
- ULONG result = 0;
-
- if (ncm->sort_type == MUIV_NList_SortType_None) return (0);
-
- if (col1 == 0) {
- if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
- result = (LONG) stricmp(entry2->title, entry1->title);
- else
- result = (LONG) stricmp(entry1->title, entry2->title);
- }
- else if (col1 == 1) {
- if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
- result = entry2->size - entry1->size;
- else
- result = entry1->size - entry2->size;
- }
- else if (col1 == 2) {
- if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
- result = entry2->time - entry1->time;
- else
- result = entry1->time - entry2->time;
- }
- else if (col1 == 3) {
- if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
- result = entry2->bitrate - entry1->bitrate;
- else
- result = entry1->bitrate - entry2->bitrate;
- }
- else if (col1 == 4) {
- if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
- result = entry2->freq - entry1->freq;
- else
- result = entry1->freq - entry2->freq;
- }
- else if (col1 == 5) {
- if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
- result = entry2->reqcount - entry1->reqcount;
- else
- result = entry1->reqcount - entry2->reqcount;
- }
- else if (col1 == 6) {
- if (ncm->sort_type & MUIV_NList_TitleMark_TypeMask)
- result = (LONG) stricmp(entry2->md5, entry1->md5);
- else
- result = (LONG) stricmp(entry1->md5, entry2->md5);
- }
-
- if ((result != 0) || (col1 == col2)) return (result);
-
- if (col2 == 0) {
- if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
- result = (LONG) stricmp(entry2->title, entry1->title);
- else
- result = (LONG) stricmp(entry1->title, entry2->title);
- }
- else if (col2 == 1) {
- if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
- result = entry2->size - entry1->size;
- else
- result = entry1->size - entry2->size;
- }
- else if (col2 == 2) {
- if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
- result = entry2->time - entry1->time;
- else
- result = entry1->time - entry2->time;
- }
- else if (col2 == 3) {
- if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
- result = entry2->bitrate - entry1->bitrate;
- else
- result = entry1->bitrate - entry2->bitrate;
- }
- else if (col2 == 4) {
- if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
- result = entry2->freq - entry1->freq;
- else
- result = entry1->freq - entry2->freq;
- }
- else if (col2 == 5) {
- if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
- result = entry2->reqcount - entry1->reqcount;
- else
- result = entry1->reqcount - entry2->reqcount;
- }
- else if (col2 == 6) {
- if (ncm->sort_type & MUIV_NList_TitleMark2_TypeMask)
- result = (LONG) stricmp(entry2->md5, entry1->md5);
- else
- result = (LONG) stricmp(entry1->md5, entry2->md5);
- }
-
- return (result);
- }
-
-
- MUIF ShareListAppMsgFunc(REG(a2) APTR obj, REG(a1) struct AppMessage **x)
- {
- struct WBArg *ap;
- struct AppMessage *amsg = *x;
- int i;
- static char buf[256];
-
- for (ap=amsg->am_ArgList, i=0; i<amsg->am_NumArgs; i++, ap++)
- {
- NameFromLock(ap->wa_Lock, buf, sizeof(buf));
- AddPart(buf, ap->wa_Name, sizeof(buf));
- DoMethod(gui->shwin, SHARE_ADDFILEN, buf);
- }
-
- return(0);
- }
-
-
- ULONG share_new(struct IClass *cl, Object *obj, struct opSet *msg)
- {
- static const struct Hook sharelistdispHook = { {NULL, NULL}, &sharelistdisp, NULL, NULL };
- static const struct Hook sharelistcompHook = { {NULL, NULL}, &sharelistcomp, NULL, NULL };
- static const struct Hook sharelistdestHook = { {NULL, NULL}, &sharelistdest, NULL, NULL };
- static const struct Hook ShareListAppMsgHook = { {NULL, NULL}, &ShareListAppMsgFunc, NULL, NULL };
-
- struct shdata *data;
- Object *list, *stat, *addbut, *adddirbut, *rembut, *remallbut;
-
- if (obj = (Object *)DoSuperNew(cl, obj,
- MUIA_HelpNode, "sharing",
- MUIA_Window_ID, MAKE_ID('S','H','A','R'),
- MUIA_Window_Title, MSG_SHARE_TITLE,
- MUIA_Window_AppWindow, TRUE,
- WindowContents, VGroup,
- MUIA_HelpNode, "sharing",
- Child, stat = TextObject,
- TextFrame,
- MUIA_Background, MUII_TextBack,
- MUIA_Text_PreParse, "\33c",
- End,
- Child, list = NListviewObject,
- MUIA_NListview_NList, NListObject,
- InputListFrame,
- MUIA_NList_Title, TRUE,
- MUIA_NList_Format, "BAR, BAR, BAR, BAR, BAR, BAR",
- MUIA_NList_DisplayHook, &sharelistdispHook,
- MUIA_NList_CompareHook2, &sharelistcompHook,
- MUIA_NList_DestructHook, &sharelistdestHook,
- MUIA_NList_MultiSelect, MUIV_NList_MultiSelect_Default,
- MUIA_NList_MinColSortable, 0,
- MUIA_CycleChain, 1,
- End,
- End,
- Child, HGroup,
- Child, addbut = SimpleButton(MSG_SHARE_ADD_GAD ),
- Child, adddirbut = SimpleButton(MSG_SHARE_ADDRECURSIVE_GAD),
- Child, rembut = SimpleButton(MSG_SHARE_REMOVE_GAD ),
- Child, remallbut = SimpleButton(MSG_SHARE_REMOVEALL_GAD ),
- End,
- End,
- TAG_MORE, msg->ops_AttrList))
- {
- data = INST_DATA(cl,obj);
- data->list = list;
- data->stat = stat;
-
-
- /* Default sort */
-
- DoMethod(list, MUIM_Set, MUIA_NList_TitleMark, 0);
- DoMethod(list, MUIM_NList_Sort3, 0, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both);
-
- /* Window notify */
-
- DoMethod(obj, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, gui->iconpanel, 1, PANEL_CLOSESHARE);
-
- /* List notifies */
-
- DoMethod(list, MUIM_Notify, MUIA_NList_DoubleClick, MUIV_EveryTime, obj, 1, SHARE_PLAY);
- DoMethod(list, MUIM_Notify, MUIA_NList_TitleClick, MUIV_EveryTime, list, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_Both);
- DoMethod(list, MUIM_Notify, MUIA_NList_TitleClick2, MUIV_EveryTime, list, 4, MUIM_NList_Sort3, MUIV_TriggerValue, MUIV_NList_SortTypeAdd_2Values, MUIV_NList_Sort3_SortType_2);
- DoMethod(list, MUIM_Notify, MUIA_NList_SortType, MUIV_EveryTime, list, 3, MUIM_Set, MUIA_NList_TitleMark, MUIV_TriggerValue);
- DoMethod(list, MUIM_Notify, MUIA_NList_SortType2, MUIV_EveryTime, list, 3, MUIM_Set, MUIA_NList_TitleMark2, MUIV_TriggerValue);
- DoMethod(list, MUIM_Notify, MUIA_AppMessage, MUIV_EveryTime, list, 3, MUIM_CallHook, &ShareListAppMsgHook, MUIV_TriggerValue);
-
- /* Button notifies */
-
- DoMethod(addbut, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, SHARE_ADD );
- DoMethod(adddirbut, MUIM_Notify, MUIA_Pressed, FALSE, obj, 1, SHARE_ADDDIR );
- DoMethod(rembut, MUIM_Notify, MUIA_Pressed, FALSE, obj, 2, SHARE_REMOVE, 0);
- DoMethod(remallbut, MUIM_Notify, MUIA_Pressed, FALSE, obj, 2, SHARE_REMOVE, 1);
-
- /* Allocate file requesters */
-
- FReqAddFiles = AllocAslRequestTags(ASL_FileRequest,
- ASLFR_TitleText, MSG_SHARE_ADD_REQ,
- ASLFR_InitialPattern, (ULONG)"#?.mp(2|3)",
- ASLFR_InitialDrawer, (ULONG)prf->dlpath,
- ASLFR_DoPatterns, TRUE,
- ASLFR_DoMultiSelect, TRUE,
- ASLFR_RejectIcons, TRUE,
- TAG_DONE);
- FReqAddDir = AllocAslRequestTags(ASL_FileRequest,
- ASLFR_TitleText, MSG_SHARE_ADDDIR_REQ,
- ASLFR_InitialDrawer, (ULONG)prf->dlpath,
- ASLFR_DrawersOnly, TRUE,
- TAG_DONE);
- FReqLibrary = AllocAslRequestTags(ASL_FileRequest,
- ASLFR_InitialFile, "Amster.shares",
- ASLFR_InitialDrawer, "PROGDIR:",
- ASLFR_RejectIcons, TRUE,
- TAG_DONE);
-
- return((ULONG)obj);
- }
- return(0);
- }
-
-
- /* Private functions */
-
-
- void add_filename(struct shdata *data, char *fname)
- {
- sharedata sd;
- struct FileInfoBlock *fib;
- BPTR lock;
-
- if (!(fib = AllocMem(sizeof(*fib), MEMF_PUBLIC))) return;
-
- if (sd = malloc(sizeof(_sharedata))) {
- memset(sd, 0, sizeof(_sharedata));
-
- strcpy(sd->title, fname);
- if (lock = Lock(fname, ACCESS_READ)) {
- if (Examine(lock, fib)) {
- sd->size = fib->fib_Size;
- if (NameFromLock(lock, sd->title, 255)) {
- if (fib->fib_DirEntryType < 0) add_shareinfo(data, sd, lock);
- else if (fib->fib_DirEntryType > 0) {
- add_recursive(data, sd, lock, sd->title);
- UnLock(lock);
- }
- }
- else UnLock(lock);
- }
- }
- }
-
- FreeMem(fib, sizeof(*fib));
- }
-
-
- void add_file(struct shdata *data, song sdl, char *fname)
- {
- sharedata sd;
- struct FileInfoBlock *fib;
- BPTR lock;
-
- if (sd = malloc(sizeof(_sharedata))) {
- memset(sd, 0, sizeof(_sharedata));
-
- if (fib = AllocMem(sizeof(*fib), MEMF_PUBLIC)) {
- if (lock = Lock(fname, ACCESS_READ)) {
- NameFromLock(lock, sd->title, 255);
- UnLock(lock);
- }
- FreeMem(fib, sizeof(*fib));
- }
-
- if (!sd->title) strcpy(sd->title, fname);
- strncpy(sd->md5, sdl->md5, 32);
- sd->size = sdl->size;
- sd->bitrate = sdl->bit;
- sd->freq = sdl->freq;
- sd->time = sdl->time;
-
- DoMethod(data->list, MUIM_NList_InsertSingle, sd, MUIV_NList_Insert_Sorted);
- numsongs++; numbytes += sd->size;
- sharechanged = TRUE;
- update_stat(data);
- if(gui_napon) nap_notifyshare(sd);
- }
-
- return;
- }
-
-
- void add_shares(struct shdata *data)
- {
- sharedata sd;
- BPTR lock;
- struct FileInfoBlock *fib;
- int i;
- u_long win;
-
- get(gui->shwin, MUIA_Window_Window, &win);
-
- if (FReqAddFiles) {
- if (AslRequestTags(FReqAddFiles, ASLFR_Window, win, TAG_DONE)) {
- if (fib = AllocMem(sizeof(*fib), MEMF_PUBLIC)) {
- for (i=0; i<FReqAddFiles->fr_NumArgs; i++) {
- if (sd = malloc(sizeof(_sharedata))) {
- memset(sd, 0, sizeof(_sharedata));
- strcpy(sd->title, FReqAddFiles->fr_Drawer);
- AddPart(sd->title, FReqAddFiles->fr_ArgList[i].wa_Name, 255);
- if (lock = Lock(sd->title, ACCESS_READ)) {
- if (Examine(lock, fib)) {
- sd->size = fib->fib_Size;
- if (NameFromLock(lock, sd->title, 255)) {
- if (fib->fib_DirEntryType < 0) add_shareinfo(data, sd, lock);
- else if (fib->fib_DirEntryType > 0) {
- add_recursive(data, sd, lock, sd->title);
- UnLock(lock);
- }
- }
- else UnLock(lock);
- }
- }
- }
- }
- FreeMem(fib, sizeof(*fib));
- }
- }
- if (sharefailed) {
- MUI_Request(gui->app, gui->shwin, 0L,
- (char *)MSG_ERROR_TITLE,
- (char *)MSG_OK_GAD,
- (char *)MSG_SHARE_ADDFAILED);
- sharefailed = FALSE;
- }
- }
- }
-
-
- void add_directory(struct shdata *data)
- {
- sharedata sd;
- BPTR lock;
- struct FileInfoBlock *fib;
- u_long win;
-
- get(gui->shwin, MUIA_Window_Window, &win);
-
- if (FReqAddDir) {
- if (AslRequestTags(FReqAddDir, ASLFR_Window, win, TAG_DONE)) {
- if (fib = AllocMem(sizeof(*fib), MEMF_PUBLIC)) {
- if (sd = malloc(sizeof(_sharedata))) {
- memset(sd, 0, sizeof(_sharedata));
- strcpy(sd->title, FReqAddDir->fr_Drawer);
- if (lock = Lock(sd->title, ACCESS_READ)) {
- if (Examine(lock, fib)) {
- sd->size = fib->fib_Size;
- if (NameFromLock(lock, sd->title, 255)) {
- if (fib->fib_DirEntryType > 0) {
- add_recursive(data, sd, lock, sd->title);
- UnLock(lock);
- }
- }
- else UnLock(lock);
- }
- }
- }
- FreeMem(fib, sizeof(*fib));
- }
- }
- if (sharefailed) {
- MUI_Request(gui->app, gui->shwin, 0L,
- (char *)MSG_ERROR_TITLE,
- (char *)MSG_OK_GAD,
- (char *)MSG_SHARE_ADDFAILED);
- sharefailed = FALSE;
- }
- }
- }
-
-
- void add_recursive(struct shdata *data, sharedata sd, BPTR dirlock, const char *dirname)
- {
- ULONG namelen;
- long len;
- struct ExAllControl *eac;
- struct ExAllData *ead;
- APTR eadata;
- BOOL more;
- char *name;
- BPTR lock;
- struct FileInfoBlock *fib;
- const long buffersize = 4096;
-
- if (dirlock) {
- namelen = strlen(dirname);
- eac = AllocDosObject(DOS_EXALLCONTROL, NULL);
- if (eac) {
- eac->eac_LastKey = 0;
- eac->eac_MatchString = 0;
- eac->eac_MatchFunc = 0;
- eadata = malloc(buffersize);
- if (eadata) {
- do {
- more = ExAll(dirlock, eadata, buffersize, ED_TYPE, eac);
- if (eac->eac_Entries > 0) {
- ead = eadata;
- do {
- len = namelen + strlen(ead->ed_Name);
- name = (char *)malloc(len+5);
- if (name) {
- strcpy(name, dirname);
- if (AddPart(name, ead->ed_Name, len+5)) {
- if (ead->ed_Type > 0) {
- lock = Lock(name, ACCESS_READ);
- if (lock) {
- add_recursive(data, sd, lock, name);
- UnLock(lock);
- }
- }
- else if (ead->ed_Type < 0) {
- if (sd = malloc(sizeof(_sharedata))) {
- memset(sd, 0, sizeof(_sharedata));
- strcpy(sd->title, name);
- if (fib = AllocMem(sizeof(*fib), MEMF_PUBLIC)) {
- lock = Lock(name, ACCESS_READ);
- if (lock) {
- if (Examine(lock, fib)) {
- sd->size = fib->fib_Size;
- add_shareinfo(data, sd, lock);
- }
- }
- }
- FreeMem(fib, sizeof(*fib));
- }
- }
- }
- free(name);
- }
- ead = ead->ed_Next;
- } while(ead);
- }
- if ((!more) && (IoErr() != ERROR_NO_MORE_ENTRIES)) break;
- if (eac->eac_Entries == 0) continue;
- } while (more);
- free(eadata);
- }
- FreeDosObject(DOS_EXALLCONTROL, eac);
- }
- }
- }
-
-
- void add_shareinfo(struct shdata *data, sharedata sd, BPTR lock)
- {
- unsigned int m_id, m_layer, m_bit, m_freq, m_mode;
- APTR buffer;
- BPTR fh;
- int i=0, j=0, len, total, col;
- long vbrbytes = 0, vbrframes = 0, vbr = 0;
- BOOL header = FALSE;
- int badhdr[10];
- char *suffix;
-
- sharedata sdtmp;
- ULONG tmp;
-
- md5_state_t state;
- md5_byte_t digest[16];
- int di;
-
- /* MP3 information source:
- http://mp3tech.free.fr/programmers/frame_header.html
- */
-
- int mp3_bitrates[14][6] = {
- /* V1L1,V1L2,V1L3,V2L1,V2L2,V2L3 */
- { 32, 32, 32, 32, 8, 8 },
- { 64, 48, 40, 48, 16, 16 },
- { 96, 56, 48, 56, 24, 24 },
- { 128, 64, 56, 64, 32, 32 },
- { 160, 80, 64, 80, 40, 40 },
- { 192, 96, 80, 96, 48, 48 },
- { 224, 112, 96, 112, 56, 56 },
- { 256, 128, 112, 128, 64, 64 },
- { 288, 160, 128, 144, 80, 80 },
- { 320, 192, 160, 160, 96, 96 },
- { 352, 224, 192, 176, 112, 112 },
- { 384, 256, 224, 192, 128, 128 },
- { 416, 320, 256, 224, 144, 144 },
- { 448, 384, 320, 256, 160, 160 }
- };
- /* V1 = MPEG Version 1
- V2 = MPEG Version 2 and Version 2.5
- L1 = Layer I
- L2 = Layer II
- L3 = Layer III
- */
-
- int mp3_frequencies[3][3] = {
- /* MPEG1, MPEG2, MPEG2.5 */
- { 44100, 22050, 11025 },
- { 48000, 24000, 12000 },
- { 32000, 16000, 8000 }
- };
-
- if (IsIn(sd->title, '"') || IsIn(sd->title, '\\')) {
- gui_debugf((char *)MSG_SHARE_ILLEGALCHARS, sd->title);
- sharefailed = TRUE;
- UnLock(lock);
- return;
- }
-
- suffix = sd->title + strlen(sd->title) - 4;
- if (stricmp(suffix, ".mp3") != 0 && stricmp(suffix, ".mp2") != 0) {
- gui_debugf((char *)MSG_SHARE_INVALIDEXTENSION, sd->title);
- sharefailed = TRUE;
- UnLock(lock);
- return;
- }
-
- GetAttr(MUIA_NList_Entries, data->list, &tmp);
- total = tmp;
-
- while (i < total) {
- DoMethod(data->list, MUIM_NList_GetEntry, i, &sdtmp);
- if (sdtmp) if (strcmp(sd->title, sdtmp->title) == 0) {
- gui_debugf((char *)MSG_SHARE_EXISTS, sd->title);
- sharefailed = TRUE;
- UnLock(lock);
- return;
- }
- i++;
- }
-
- if (fh = OpenFromLock(lock)) {
- if (buffer = AllocMem(300032, MEMF_ANY)) {
-
- md5_init(&state);
-
- len = Read(fh, buffer, 300032);
- if (len > 0) {
-
- md5_append(&state, (const md5_byte_t *)buffer, len);
- md5_finish(&state, digest);
- for (di = 0; di < 16; ++di)
- sprintf(sd->md5+di*2, "%02x", digest[di]);
-
- /* Only check first 128 kB for valid MP3 header */
- if (len > 128*1024) len = 128*1024;
-
- /* Check for VBR */
- for (i=0; i<len; i++) {
- if (*((unsigned char *)buffer+i) == 'X')
- if (*((unsigned char *)buffer+i+1) == 'i')
- if (*((unsigned char *)buffer+i+2) == 'n')
- if (*((unsigned char *)buffer+i+3) == 'g') {
- j = i + 7;
- if ((*((char *)buffer+j) & 1) && ((*((char *)buffer+j) & 2) >> 1)) {
- j++;
- vbrframes = *((unsigned long *)buffer+j/4);
- vbrbytes = *((unsigned long *)buffer+(j+4)/4);
- j += 7;
- }
- if (vbrframes > 0 && vbrbytes > 0) vbr = ((vbrbytes / vbrframes) * 1000) / 3265;
- break;
- }
- }
-
- i = j;
- if (stcd_i(buffer, badhdr) == 8 && i < 417) i = 417;
- /* Work-around for "MpegDJ Encoder" bug */
-
- while (!header && i<len-3) {
- /* Seek until synchronization is found (%11111111.111xxxxx) */
- if (*((unsigned char *)buffer+i) == 255) {
- if (*((unsigned char *)buffer+i+1) >= 224) {
-
- /* MPEG Audio version ID
- 00 - MPEG Version 2.5 (later extension of MPEGĀ 2)
- 01 - reserved
- 10 - MPEG Version 2 (ISO/IEC 13818-3)
- 11 - MPEG Version 1 (ISO/IEC 11172-3)
- */
-
- m_id = 3 - ((*((char *)buffer+i+1) & 24)>>3);
- if (m_id == 3) m_id = 1;
-
- /* Layer description
- 00 - reserved
- 01 - Layer III
- 10 - Layer II
- 11 - Layer I
- */
-
- m_layer = 4 - ((*((char *)buffer+i+1) & (2+4))>>1);
- m_bit = (*((char *)buffer+i+2) & (16+32+64+128))>>4;
- m_freq = (*((char *)buffer+i+2) & (4+8))>>2;
-
- /* Channel Mode
- 00 - Stereo
- 01 - Joint stereo (Stereo)
- 10 - Dual channel (2 mono channels)
- 11 - Single channel (Mono)
- */
-
- m_mode = (*((char *)buffer+i+3) & (64+128))>>6;
-
- col = m_layer-1;
- if (m_id == 1) col=col+3;
-
- if (m_bit>0 && m_bit<15 && m_freq < 3 && m_layer < 4 && m_id != 2) {
-
- header = TRUE;
-
- sd->freq = mp3_frequencies[m_freq][m_id];
- if (vbr > 0) sd->bitrate = vbr;
- else sd->bitrate = mp3_bitrates[m_bit-1][col];
-
- if (m_layer == 2) { /* Sanity checks */
- if ((sd->bitrate == 32 || sd->bitrate == 48 || sd->bitrate == 46 || sd->bitrate == 80) && m_mode != 3) header = FALSE;
- if ((sd->bitrate == 224 || sd->bitrate == 256 || sd->bitrate == 320 || sd->bitrate == 384) && m_mode == 3) header = FALSE;
- }
-
- sd->time = (sd->size-i)/(sd->bitrate*125);
- /* 'i' is the length of ID3v2 tag. ID3v1 size is always 128 bytes,
- so it's not worth the overhead to check for this.
- 128 bytes of a 128 kbps MP3 = 0.000008 seconds! */
- }
- }
- }
- i++;
- }
- }
- FreeMem(buffer, 300032);
- }
- Close(fh);
- if (header) {
- DoMethod(data->list, MUIM_NList_InsertSingle, sd, MUIV_NList_Insert_Sorted);
- numsongs++; numbytes += sd->size;
- sharechanged = TRUE;
- update_stat(data);
- if(gui_napon) nap_notifyshare(sd);
- }
- else {
- gui_debugf((char *)MSG_SHARE_ADDERROR, sd->title, sd->size, sd->bitrate, sd->freq);
- sharefailed = TRUE;
- }
- }
- else UnLock(lock);
-
- }
-
-
- void notify_shares(struct shdata *data)
- {
- sharedata sd;
- u_long tmp;
- int i, total;
-
- if (!gui_napon) return;
-
- GetAttr(MUIA_NList_Entries, data->list, &tmp);
- total = tmp;
-
- if (total > 0) {
- gui_stat((char *)MSG_STATUS2_NOTIFYALL);
- for (i=0; i<total; i++) {
- DoMethod(data->list, MUIM_NList_GetEntry, i, &sd);
- if (!sd) break;
- nap_notifyshare(sd);
- }
- }
- }
-
-
- void remove_shares(struct shdata *data, long t)
- {
- sharedata sd;
- u_long tmp;
- int total;
-
- GetAttr(MUIA_NList_Entries, data->list, &tmp);
- total = tmp;
-
- if (total == 0) return;
-
- switch(t) {
- case 0: /* Remove marked */
- set(data->list, MUIA_NList_Quiet, MUIV_NList_Quiet_Visual);
- DoMethod(data->list, MUIM_NList_Remove, MUIV_NList_Remove_Selected);
- update_stat(data);
- set(data->list,MUIA_NList_Quiet, MUIV_NList_Quiet_None);
- break;
- case 1: /* Remove all */
- set(data->list, MUIA_NList_Quiet, MUIV_NList_Quiet_Visual);
- for (;;) {
- DoMethod(data->list, MUIM_NList_GetEntry, 0, &sd);
- if (!sd) break;
- DoMethod(data->list, MUIM_NList_Remove, MUIV_NList_Remove_First);
- }
- update_stat(data);
- set(data->list, MUIA_NList_Quiet, MUIV_NList_Quiet_None);
- break;
- }
- sharechanged = TRUE;
- }
-
-
- void save_shares(struct shdata *data)
- {
- sharedata sd;
- int i;
- BPTR fh;
- char buf[512], *tmp;
-
- strcpy(buf, FReqLibrary->fr_Drawer);
- AddPart(buf, FReqLibrary->fr_File, 511);
-
- fh = Open(buf, MODE_NEWFILE);
- if (!fh) return;
-
- for (i=0; ; i++) {
- DoMethod(data->list, MUIM_NList_GetEntry, i, &sd);
- if (!sd) break;
- tmp = strrep(sd->title, "\"", "*\"");
- sprintf(buf, "\"%s\" %s %ld %ld %ld %ld REQCOUNT %ld\n", tmp, sd->md5, sd->size, sd->bitrate, sd->freq, sd->time, sd->reqcount);
- free(tmp);
- Write(fh, buf, strlen(buf)); /* Should be buffered, check FWrite */
- }
-
- Close(fh);
- sharechanged = FALSE;
- }
-
-
- void save_shares_as(struct shdata *data)
- {
- u_long win;
-
- get(gui->shwin, MUIA_Window_Window, &win);
- if (FReqLibrary) {
- if (AslRequestTags(FReqLibrary,
- ASLFR_Window, win,
- ASLFR_TitleText, MSG_SHARE_SAVEAS,
- ASLFR_DoSaveMode, TRUE,
- TAG_DONE)) {
- save_shares(data);
- }
- }
- }
-
-
- void load_shares(struct shdata *data)
- {
- sharedata sd;
- int line = 0;
- BPTR fh;
- char buf[512], sharefile[512];
- LONG argarray[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
- UBYTE *argstr = "PATH/A,MD5/A,SIZE/A/N,BITRATE/A/N,FREQUENCY/A/N,TIME/A/N,REQCOUNT/K/N";
- struct RDArgs *rdargs;
-
- remove_shares(data, 1);
-
- strcpy(sharefile, FReqLibrary->fr_Drawer);
- AddPart(sharefile, FReqLibrary->fr_File, 511);
-
- if (fh = Open(sharefile, MODE_OLDFILE)) {
- set(data->list,MUIA_NList_Quiet, MUIV_NList_Quiet_Visual);
-
- while (FGets(fh, buf, 512)) {
- line++;
- if (rdargs = AllocDosObject(DOS_RDARGS, NULL)) {
- rdargs->RDA_Buffer = NULL;
- rdargs->RDA_Source.CS_Buffer = buf;
- rdargs->RDA_Source.CS_Length = strlen(buf);
- if (ReadArgs(argstr, argarray, rdargs)) {
-
- sd = malloc(sizeof(_sharedata));
-
- strcpy(sd->title, (char *)argarray[ ARG_PATH ]);
- strcpy(sd->md5, (char *)argarray[ ARG_MD5 ]);
- sd->size = *((long *)argarray[ ARG_SIZE ]);
- sd->bitrate = *((long *)argarray[ ARG_BITRATE ]);
- sd->freq = *((long *)argarray[ ARG_FREQ ]);
- sd->time = *((long *)argarray[ ARG_TIME ]);
- if (argarray[ARG_REQCOUNT]) sd->reqcount = *((long *)argarray[ ARG_REQCOUNT ]);
- else sd->reqcount = 0;
-
- DoMethod(data->list, MUIM_NList_InsertSingle, sd, MUIV_NList_Insert_Bottom);
- numsongs++; numbytes += sd->size;
- if (gui_napon) nap_notifyshare(sd);
-
- FreeArgs(rdargs);
- }
- else gui_debugf((char *)MSG_PARSE_ERROR, sharefile, line);
- FreeDosObject(DOS_RDARGS, rdargs);
- }
- }
-
- set(data->list, MUIA_NList_Quiet, MUIV_NList_Quiet_None);
- update_stat(data);
-
- Close(fh);
- }
- sharechanged = FALSE;
- }
-
-
- void load_shares_as(struct shdata *data)
- {
- u_long win;
-
- get(gui->shwin, MUIA_Window_Window, &win);
- if (FReqLibrary) {
- if (AslRequestTags(FReqLibrary,
- ASLFR_Window, win,
- ASLFR_TitleText, MSG_SHARE_LOADAS,
- TAG_DONE)) {
- load_shares(data);
- }
- }
- }
-
-
- void update_stat(struct shdata *data)
- {
- static char buf[100], totalsize[8];
- char descriptor[16];
- unsigned long number, tempnumber;
-
- if (numbytes >= (1024*1024*1024)) {
- strcpy(descriptor, MSG_SHARE_STAT_GB);
- tempnumber = numbytes/1024/1024*10/1024;
- number = tempnumber/10;
- tempnumber = tempnumber-(number*10);
- sprintf(totalsize,"%d.%d", number, tempnumber);
- }
- else if (numbytes >= (1024*1024)) {
- strcpy(descriptor, MSG_SHARE_STAT_MB);
- tempnumber = numbytes/1024*10/1024;
- number = tempnumber/10;
- tempnumber = tempnumber-(number*10);
- sprintf(totalsize, "%d.%d", number, tempnumber);
- }
- else {
- strcpy(descriptor, MSG_SHARE_STAT_KB);
- number = numbytes/1024;
- sprintf(totalsize, "%d", number);
- }
-
- sprintf(buf, MSG_SHARE_STAT_TMP, numsongs, totalsize, descriptor);
- set(data->stat, MUIA_Text_Contents, buf);
- }
-
-
- void play_share(struct shdata *data)
- {
- sharedata sd;
- char buf[1024], *command;
-
- DoMethod(data->list, MUIM_NList_GetEntry, MUIV_NList_GetEntry_Active, &sd);
- if (sd) {
- if (prf->scripts[PRFE_PLAYMP3]) {
- sprintf(buf, "Run <>NIL: %s", prf->scripts[PRFE_PLAYMP3]);
- command = strrep(buf, "%f", sd->title);
- Execute(command, 0, 0);
- free(command);
- }
- }
- }
-
-
- void upload_req(char *user, char *fname)
- {
- DoMethod(gui->shwin, SHARE_UPLOAD, user, fname);
- }
-
-
- void upload_file_confirm(struct shdata *data, char *user, char *fname)
- /* Continued from upload_req() */
- {
- sharedata sd;
- song s;
- int i=0, total;
- ULONG tmp;
- BOOL found = FALSE;
- char *path;
-
- GetAttr(MUIA_NList_Entries, data->list, &tmp);
- total = tmp;
-
- gui_debugf((char *)MSG_SHARE_REQFILE, user, fname);
-
- while (i<total && !found) {
- DoMethod(data->list, MUIM_NList_GetEntry, i, &sd);
- if (sd) {
- path = MakeWinPath(sd->title);
- if (strcmp(path, fname) == 0) found = TRUE;
- free(path);
- }
- i++;
- }
-
- if (!found) {
- gui_debug((char *)MSG_SHARE_NOTFOUND);
- return;
- }
-
- s = malloc(sizeof(_song));
- if (!s) return;
- memset(s, 0, sizeof(_song));
-
- s->title = strdup(sd->title);
- s->md5 = strdup(sd->md5);
- s->size = sd->size;
- s->bit = sd->bitrate;
- s->freq = sd->freq;
- s->time = sd->time;
- s->user = strdup(user);
- /* At this point we don't know IP and link speed - can't complete the struct */
-
- ul_addq(s);
- }
-
-
- void update_count(struct shdata *data, char *fname)
- {
- sharedata sd;
- int i;
- long pos;
-
- for (i=0; ; i++) {
- DoMethod(data->list, MUIM_NList_GetEntry, i, &sd);
- if (!sd) return;
- if (strcmp(sd->title, fname) == 0) break;
- }
-
- /* Update statistics (count) */
- sd->reqcount++;
- sharechanged = TRUE;
-
- pos = MUIV_NList_GetPos_Start;
- DoMethod(data->list, MUIM_NList_GetPos, sd, &pos);
- DoMethod(data->list, MUIM_NList_Redraw, pos);
- }
-
-
- void nap_notifyshare(sharedata sd)
- {
- char *path, *suffix;
-
- /* In case invalid files were added manually or with an earlier version */
- if (IsIn(sd->title, '"') || IsIn(sd->title, '\\')) {
- gui_debugf((char *)MSG_SHARE_ILLEGALCHARS, sd->title);
- return;
- }
-
- suffix = sd->title + strlen(sd->title) - 4;
- if (stricmp(suffix, ".mp3") != 0 && stricmp(suffix, ".mp2") != 0) {
- gui_debugf((char *)MSG_SHARE_INVALIDEXTENSION, sd->title);
- return;
- }
-
- path = MakeWinPath(sd->title);
- sprintf(nap_buf, "\"%s\" %s %ld %ld %ld %ld", path, sd->md5, sd->size, sd->bitrate, sd->freq, sd->time);
- free(path);
- nap_send(NAPC_NOTIFYSHARE);
- }
-
-
- char *strrep(char *str1, char *old_str, char *new_str)
- {
- char *str;
- int len, i;
-
- if (!(str = malloc(1024))) return str1;
- str[0] = '\0';
-
- for (i=0; i<strlen(str1); i++) {
- if (strncmp(str1+i, old_str, strlen(old_str)) == 0) {
- strcat(str, new_str);
- i += strlen(old_str)-1;
- }
- else {
- len = strlen(str);
- str[len] = str1[i];
- str[len+1] = '\0';
- }
- }
-
- return str;
- }
-
-
- char *MakeWinPath(char *AmigaPath)
- /* PRE: The AmigaPath must contain max. 1 colon */
- {
- char *WinPath;
- int i, j;
-
- if (!(WinPath = malloc(strlen(AmigaPath)+2))) return AmigaPath;
-
- for (i=0, j=0; i<strlen(AmigaPath); i++, j++) {
- if (AmigaPath[i] == '/') WinPath[j] = '\\';
- else if (AmigaPath[i] == ':') {
- WinPath[j++] = ':';
- WinPath[j] = '\\';
- }
- else WinPath[j] = AmigaPath[i];
- }
- WinPath[j] = '\0';
-
- return WinPath;
- }
-
-
- BOOL IsIn(char *string, char c)
- {
- int i;
-
- for (i=0; i<strlen(string); i++)
- if (string[i] == c) return TRUE;
-
- return FALSE;
- }
-